//
// Created by 麻再挺 on 2021/12/8.
//

#include "stack_queue_menu.h"

/**
 * 栈实现
 */
void stack_impl();

/**
 * 数值转换
 */
void conversion();

/**
 * 链表队列实现
 */
void link_queue_impl();

/**
 * 循环队列实现
 */
void cycle_queue_impl();

/**
 * 栈与队列运行主函数
 */
void stack_queue_run() {
    // 菜单
    int menu = -1;
    // 是否运行
    Status is_run = TRUE;
    while (is_run) {
        printf("╔═══════════════════════════════════════════════╗\n");
        printf("║                     线性表                    ║\n");
        printf("║ 1: 栈                                         ║\n");
        printf("║ 2: 数值转换                                   ║\n");
        printf("║ 3: 队列                                       ║\n");
        printf("║ 4: 循环队列                                   ║\n");
        printf("║ 0: 退出                                       ║\n");
        printf("╚═══════════════════════════════════════════════╝\n");
        printf("请选择功能菜单: ");
        fflush(stdout);
        scanf("%d", &menu);

        switch (menu) {
            case 0:
                // 退出
                is_run = FALSE;
                break;
            case 1:
                stack_impl(); // 栈
                break;
            case 2:
                conversion(); // 进制转换
                break;
            case 3:
                link_queue_impl(); // 链表队列
                break;
            case 4:
                cycle_queue_impl(); // 循环队列
                break;
            default:
                printf("输入异常\n");
                break;
        }
    }
}

/**
 * 栈实现
 */
void stack_impl() {
    Stack stack;
    // 初始化
    Status res = Init_Stack(&stack);
    if (res != OK) {
        printf("初始化异常\n");
        return;
    }
    printf("初始化栈: ");
    Stack_Print(&stack);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Stack_Push(&stack, (SElemType) (10 + i));
    }
    printf("push添加数据: ");
    Stack_Print(&stack);

    // 将最后一个元素删除
    SElemType popElem;
    Stack_Pop(&stack, &popElem);
    printf("pop数据: %d\n", popElem);
    printf("pop后栈数据: ");
    Stack_Print(&stack);

    // 判断列表是否为空
    res = Stack_Empty(&stack);
    if (res == TRUE) {
        printf("栈为空\n");
    } else {
        printf("栈不为空\n");
    }

    // 获取列表长度
    int length = Stack_Length(&stack);
    printf("栈长度为: %d\n", length);

    // 获取栈顶元素
    SElemType topElem;
    Stack_GetTop(&stack, &topElem);
    printf("栈顶元素: %d\n", topElem);
    Stack_GetTop(&stack, &topElem);
    printf("栈顶元素: %d\n", topElem);

    // 清空栈
    Clear_Stack(&stack);
    printf("清空后栈数据: ");
    Stack_Print(&stack);

    // 销毁栈
    Destroy_Stack(&stack);
    printf("栈已销毁\n");
}

/**
 * 数值转换
 * 对于输入的任意一个非负十进制整数打印其 8 进制数
 */
void conversion() {
    Stack stack;
    // 初始化
    Init_Stack(&stack);
    // 非负十进制整数
    int num = 128;
    while (num) {
        Stack_Push(&stack, num % 8);
        num = num / 8;
    }
    while (!Stack_Empty(&stack)) {
        SElemType elem;
        Stack_Pop(&stack, &elem);
        printf("%d", elem);
    }
    printf("\n");
    Destroy_Stack(&stack);
}

void link_queue_impl() {
    LinkQueue queue;
    // 初始化
    Status res = Link_Queue_Init(&queue);
    if (res != OK) {
        printf("初始化异常\n");
        return;
    }
    // 入队
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Link_Queue_Enter(&queue,  (10 + i));
    }
    printf("入队数据: ");
    Link_Queue_Print(&queue);
    // 出队数据
    QElemType deElem;
    Link_Queue_Deter(&queue, &deElem);
    printf("出队数据: %d\n", deElem);
    Link_Queue_Deter(&queue, &deElem);
    printf("出队数据: %d\n", deElem);
    printf("出队后数据: ");
    Link_Queue_Print(&queue);

    // 判断队列是否为空
    res = Link_Queue_Empty(&queue);
    if (res == TRUE) {
        printf("队列为空\n");
    } else {
        printf("队列不为空\n");
    }

    // 获取队列长度
    int length = Link_Queue_Length(&queue);
    printf("队列长度为: %d\n", length);

    // 获取队首元素
    QElemType headElem;
    Link_Queue_GetHead(&queue, &headElem);
    printf("队首元素: %d\n", headElem);

    // 清空栈
    Link_Queue_Clear(&queue);
    printf("清空后队列数据: ");
    Link_Queue_Print(&queue);

    // 销毁栈
    Link_Queue_Destroy(&queue);
    printf("队列已销毁\n");
}

void cycle_queue_impl() {
    CQQueue queue;
    // 初始化
    Status res = Cycle_Queue_Init(&queue);
    if (res != OK) {
        printf("初始化异常\n");
        return;
    }
    // 入队
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Cycle_Queue_Enter(&queue,  (10 + i));
    }
    printf("入队数据: ");
    Cycle_Queue_Print(&queue);
    // 出队数据
    CQElemType deElem;
    Cycle_Queue_Deter(&queue, &deElem);
    printf("出队数据: %d\n", deElem);
    Cycle_Queue_Deter(&queue, &deElem);
    printf("出队数据: %d\n", deElem);
    printf("出队后数据: ");
    Cycle_Queue_Print(&queue);

    // 判断队列是否为空
    res = Cycle_Queue_Empty(&queue);
    if (res == TRUE) {
        printf("队列为空\n");
    } else {
        printf("队列不为空\n");
    }

    // 获取列表长度
    int length = Cycle_Queue_Length(&queue);
    printf("队列长度为: %d\n", length);

    // 获取队首元素
    CQElemType headElem;
    Cycle_Queue_GetHead(&queue, &headElem);
    printf("队首元素: %d\n", headElem);

    // 清空栈
    Cycle_Queue_Clear(&queue);
    printf("清空后队列数据: ");
    Cycle_Queue_Print(&queue);

    // 销毁栈
    Cycle_Queue_Destroy(&queue);
    printf("队列已销毁\n");
}